在填寫表單時也常會看到勾選框,使用者可以明確的看到每個選項,並透過一個點擊的簡單操作就能改變選取狀態,選取完後不會立即執行動作,需要搭配按鈕進行提交(可以讓使用者多想一下)
一樣先思考 checkbox
有哪些狀態 🤔
disabled
禁止選取特別要注意的就是 <input type="checkbox">
時是可以分成單選——用來詢問是某同意網站隱私條款或是多選——問剉冰要加幾種配料等等的情況 🍧
true / false
: 將變數預設空值或填入 boolean,並將其與 v-model
綁訂,ckeckbox 此時無須給予 value 值,元件將回傳 true / false。當填入 true 為勾選,反之 false 為取消勾選。v-model
綁訂,ckeckbox 此時必須給予 value 值,元件將回傳 checkbox 代表的 value 值。變數內預先填入 checkbox 的 value 值可以產生預先勾選效果。v-model
綁定同一個變數。陣列內預先填入 checkbox 的 value 值可以產生預先勾選效果。<input>
包在 <label>
裡面,如此即便不使用 id
和 for
也能進行連動<script lang="ts" setup>
export interface CheckboxPropsType {
/** 標籤 */
label?: string
/** 預設是否勾選 */
checked?: boolean
/** 是否禁用 */
disabled?: boolean
/** name 標籤(group 使用) */
name?: string
/** input 選項代表的值 */
value?: any
/** 響應式值,如果傳入為 array 則為多選 */
modelValue?: any
}
const props = withDefaults(defineProps<CheckboxPropsType>(), {
label: '',
name: '',
value: '',
modelValue: ''
})
type EmitsEvent = (e: 'update:modelValue', value: any) => void
const emits = defineEmits<EmitsEvent>()
const ck = ref(props.checked)
const onChange = (): void => {
ck.value = !ck.value
}
const localValue = computed({
get: () => props.modelValue,
set: (newValue) => emits('update:modelValue', newValue)
})
</script>
<template>
<div>
<label
class="flex items-center"
:class="disabled ? ' cursor-not-allowed opacity-50' : 'cursor-pointer'"
>
<input
v-model="localValue"
type="checkbox"
class="hidden"
:disabled="disabled"
:name="name"
:value="value"
@change="onChange"
>
<span
class="relative inline-flex size-4 flex-none rounded border border-primary-500 transition-all duration-150 mr-3"
:class="
ck
? 'ring-primary-500 bg-primary-600 ring-2 ring-offset-2'
: 'bg-white'
"
>
<Icon
v-if="ck"
name="lucide:check"
size="14"
class="m-auto block text-white"
/>
</span>
<span
v-if="label"
class="text-sm leading-6 text-slate-500"
>
{{ label }}
</span>
</label>
</div>
</template>
最後出來的效果是這樣~
<script lang="ts" setup>
const option2 = ref(['Orange'])
const options = ref([
{
value: 'Orange',
label: 'Orange'
},
{
value: 'Apple',
label: 'Apple'
},
{
value: 'Banana',
label: 'Banana'
}
])
</script>
<template>
<div class="relative">
<div class="flex flex-col text-xl gap-4 mb-4">
<h3>Checkbox 狀態</h3>
<div class="flex flex-wrap gap-4">
<Checkbox
label="Checked"
checked
/>
<Checkbox
label="UnChecked"
/>
<Checkbox
label="Checked disabled"
disabled
/>
<Checkbox
label="UnChecked disabled"
checked
disabled
/>
</div>
</div>
<div class="flex flex-col text-xl gap-4">
<h3>Checkbox 多選</h3>
<div class="flex flex-wrap gap-4 items-center">
<div
v-for="(item, i) in options"
:key="i"
>
<Checkbox
v-model="option2"
:label="item.label"
name="group"
:value="item.value"
:checked="option2.includes(item.value)"
/>
</div>
<div class="text-slate-900">
Selected: {{ option2 }}
</div>
</div>
</div>
</div>
</template>